import sys

import win32com.client


def get_tree(product, tree=None):
    if tree is None:
        tree = {}
    tree['__product__'] = product
    try:
        tree['__name__'] = product.Name
        tree['__part_number__'] = product.PartNumber
        tree['__doc_name__'] = product.ReferenceProduct.Parent.Name
        tree['__doc_fullname__'] = product.ReferenceProduct.Parent.FullName
        tree['__sublist__'] = {}

        cat_sublist = product.ReferenceProduct.Parameters.SubList(product.ReferenceProduct, False)
        for i in range(cat_sublist.Count):
            name = cat_sublist.Item(i + 1).Name
            name = str(name).split("\\")[-1]
            tree['__sublist__'][name] = cat_sublist.Item(i + 1).Value
    except Exception as ex:
        # print('Exception', product.Name, ex)
        pass

    for product1 in product.products:
        tree[product1.name] = get_tree(product1)

    return tree


def get_tree_relation(product, tree=None):
    if tree is None:
        tree = {}
    try:
        pass
        # tree['__name__'] = product.Name
        # tree['__part_number__'] = product.PartNumber

    except Exception as ex:
        # print('Exception', product.Name, ex)
        pass

    for product1 in product.products:
        tree[product1.name] = get_tree_relation(product1)

    return tree


product_list = []


def get_product_list(product):
    global product_list
    product_list.append(product)
    for product1 in product.products:
        get_product_list(product1)

    return product_list


def get_tree_name(product, tree_prop=None):
    if tree_prop is None:
        tree_prop = {}
    try:
        tree_prop[product.name] = get_name(product)
    except Exception as ex:
        # print('Exception', product.Name, ex)
        pass
    global product_list
    product_list = []
    for product1 in get_product_list(product):
        tree_prop[product1.name] = get_name(product1)

    return tree_prop


def get_tree_prop(product, tree_prop=None):
    if tree_prop is None:
        tree_prop = {}
    try:
        tree_prop[product.name] = get_prop(product)
    except Exception as ex:
        # print('Exception', product.Name, ex)
        pass
    global product_list
    product_list = []
    for product1 in get_product_list(product):
        tree_prop[product1.name] = get_prop(product1)

    return tree_prop


def get_prop(product):
    tree = {}
    cat_sublist = product.ReferenceProduct.Parameters.SubList(product.ReferenceProduct, False)
    for i in range(cat_sublist.Count):
        name = cat_sublist.Item(i + 1).Name
        name = str(name).split("\\")[-1]
        tree[name] = cat_sublist.Item(i + 1).Value
    return tree


def get_name(product):
    name = product.PartNumber
    return name


def get_tree_value(tree, key=[]):
    value = tree

    for k in key:
        if k not in value:
            return None

        value = value[k]

    return value


def get_tree_keys(tree, keys=None, prefix=None):
    if keys is None:
        keys = [[]]
    if prefix is None:
        prefix = []

    for k in tree:
        if not k.startswith("__"):
            keys.append(prefix + [k])
            get_tree_keys(tree[k], keys, prefix + [k])

    return keys


def get_user_property(product, name):
    try:
        property = product.ReferenceProduct.Parameters.SubList(product.ReferenceProduct, False).Item(name)
        return property.Value
    except:
        return None


def set_user_property(product, name, value):
    try:
        property = product.ReferenceProduct.Parameters.SubList(product.ReferenceProduct, False).Item(name)
        property.Value = value
    except Exception as ex:
        # print('Exception', ex)
        property = product.ReferenceProduct.UserRefProperties.CreateString(name, value)

    assert property.Value == value


if __name__ == '__main__':
    catia = win32com.client.Dispatch('CATIA.Application')
    active_product = catia.ActiveDocument.Product
    tree_name = get_tree_name(active_product)
    tree_relation = get_tree_relation(active_product)
    tree_prop = get_tree_prop(active_product)
    print(tree_name)
    print(tree_relation)
    print(tree_prop)

    sys.exit()
